
#include "stdafx.h"

#include "csvline.h"
#include "infdoc.h"
#include "BodyView.h"
#include "exheader.h"

static const unsigned	FMT_HEADER = ( HDF_CENTER | HDF_RIGHT ); //	HDF_LEFT
static const LPWSTR		COL_HEADER[2] = { L"(MORE)", L"(less)" };
int CSortHeaderCtrl::ICON_WIDTH(1);

void CSortHeaderCtrl::DrawHeadItem(HDC aDC, LPHDITEM phdi, CRect arect)
{
	CDC dc;
	VERIFY( dc.Attach(aDC) );

	// save the device context.
		const int iSavedDC = dc.SaveDC();
		// draw the background,
//		CBrush brush( GetSysColor( COLOR_3DFACE ) );
//		dc.FillRect( rc, &brush );
			
	//RIFY( GetItem( lpDrawItemStruct->itemID, &hditem ) );
	// determine the format for drawing the column label.
	UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER | DT_END_ELLIPSIS ;
	switch (phdi->fmt)
	{
	case HDF_CENTER	: uFormat |= DT_CENTER;
		break;
	case HDF_RIGHT	: uFormat |= DT_RIGHT;
		break;
		default:	uFormat |= DT_LEFT;
	}		

	// adjust the rect if the mouse button is pressed on it.
//	if( lpDrawItemStruct->itemState == ODS_SELECTED )	?

	CRect rcIcon( arect );
	int iOffset = ( rcIcon.bottom - rcIcon.top ) / 4;

	// adjust the rect further if the sort arrow is to be displayed.
//	if(phdi->lParam) 
	arect.right -= 3 * iOffset;	//	shuld be always
//	arect.left += iOffset;
//	arect.right -= iOffset;
	arect.InflateRect(0-iOffset, 0);
	// draw the column label.
	if( arect.left < arect.right ) dc.DrawText( phdi->pszText, -1, arect, uFormat );

	//(phdi->lParam) // draw the sort arrow.

	// set up the pens to use for drawing the arrow.
	CPen penLight( PS_SOLID, 1, GetSysColor( COLOR_3DHILIGHT ) );
	CPen penShadow( PS_SOLID, 1, GetSysColor( COLOR_3DSHADOW ) );
	CPen* pOldPen = dc.SelectObject( &penLight );

	if(phdi->lParam)
	{
		// draw the arrow pointing upwards.
		dc.MoveTo( rcIcon.right - 2 * iOffset, iOffset);
		dc.LineTo( rcIcon.right - iOffset, rcIcon.bottom - iOffset - 1 );
		dc.LineTo( rcIcon.right - 3 * iOffset - 2, rcIcon.bottom - iOffset - 1 );
			dc.SelectObject( &penShadow );
		dc.MoveTo( rcIcon.right - 3 * iOffset - 1, rcIcon.bottom - iOffset - 1 );
		dc.LineTo( rcIcon.right - 2 * iOffset, iOffset - 1);		
	}
	else
	{
		// draw the arrow pointing downwards.
		dc.MoveTo( rcIcon.right - iOffset - 1, iOffset );
		dc.LineTo( rcIcon.right - 2 * iOffset - 1, rcIcon.bottom - iOffset );
			dc.SelectObject( &penShadow );
		dc.MoveTo( rcIcon.right - 2 * iOffset - 2, rcIcon.bottom - iOffset );
		dc.LineTo( rcIcon.right - 3 * iOffset - 1, iOffset );
		dc.LineTo( rcIcon.right - iOffset - 1, iOffset );		
	}

	dc.SelectObject( pOldPen );	// restore the pen.

	// restore the previous device context.
	VERIFY( dc.RestoreDC( iSavedDC ) );

	// detach the device context before returning.
	dc.Detach();
}

void CSortHeaderCtrl::OnClick(HWND ahandle, int acol, unsigned anwheel)
{
	int count = ::SendMessage(ahandle, HDM_GETITEMCOUNT, 0, 0L);
	HDITEMW hditem = { HDI_FORMAT | HDI_LPARAM, 0, NULL };
	for (int i(0); i < count; ++i)
	{
		hditem.fmt = 0;
		::SendMessage(ahandle, HDM_GETITEM, i, (LPARAM) (& hditem));
		hditem.lParam = 0;
		if (acol == i) 
		{
			hditem.fmt |= HDF_OWNERDRAW;
			hditem.lParam = anwheel;
		}
			else hditem.fmt &= (~HDF_OWNERDRAW);
//		hditem.mask = HDI_FORMAT;
		::SendMessage(ahandle, HDM_SETITEM, i, (LPARAM) (& hditem));
	//Header->SetItem(i, & hditem);
	}
}

void CSortHeaderCtrl::DrawItem(LPDRAWITEMSTRUCT lpdata)
{
	HWND	hwndItem = lpdata->hwndItem;
	WCHAR	szText[MAX_PATH + 1];
		* szText = 0;	//		hditem.pszText = szText;
	HD_ITEM hditem = { HDI_TEXT | HDI_FORMAT | HDI_LPARAM, 0, szText, };
		hditem.cchTextMax = MAX_PATH;
	::SendMessage(hwndItem, HDM_GETITEM, lpdata->itemID, (LPARAM) (& hditem));
//hditem.cchTextMax = ::abs(hditem.cchTextMax);
	if (hditem.lParam)
	{
		hditem.fmt &= FMT_HEADER;
		hditem.lParam ^= ((m_nArrow >> 1) << 1);
		if (!(* szText)) 
		{
			if (hditem.lParam) hditem.lParam = 1;
			hditem.pszText = COL_HEADER[hditem.lParam];
			hditem.cchTextMax = 6;
		}
		DrawHeadItem(lpdata->hDC, & hditem, lpdata->rcItem);
	}
}

BOOL CSortHeaderCtrl::OnChildNotify(UINT amsg, WPARAM wparam, LPARAM lparam, LRESULT* presult)
{
	NMHDR *pNMHDR = (LPNMHDR) lparam;

	if ((!amsg) && (!presult) && (!lparam))
	{
		HDITEMW hdi = { HDI_LPARAM | HDI_FORMAT, 0, NULL };
		int count = GetItemCount();
		if (wparam)	//	regular or registry mode
			for(int i(0); i < count; ++i) 
			{
		//di.lParam = 0;	//	hdi.fmt = HDF_OWNERDRAW;
				hdi.cxy = 0;
				hdi.mask |= HDI_WIDTH;
				GetItem(i, & hdi);
				if (hdi.cxy < ICON_WIDTH) hdi.cxy = ICON_WIDTH << 1;
					else hdi.mask &= (~HDI_WIDTH);
				hdi.fmt &= (~HDF_OWNERDRAW);
				hdi.lParam = 0;

				SetItem(i, & hdi);
			}
		else {
			hdi.fmt = HDF_STRING | HDF_LEFT;
			for(int i(0); i < count; ++i) 
				SetItem(i, & hdi);
		}
		return TRUE;	//	here is necessary utilization
	}

	if ((amsg == WM_NOTIFY) && (pNMHDR->hwndFrom))
		if ((pNMHDR->code == HDN_ITEMCLICKW) ||
			(pNMHDR->code == HDN_ITEMCLICKA))
		{
			++m_nArrow;
			LPNMHEADER phdr = (LPNMHEADER ) pNMHDR;
			HWND hwndFrom = (phdr->hdr).hwndFrom;
			OnClick(hwndFrom, phdr->iItem, m_nArrow);
			return FALSE;	//	container is next
		}

	return CHeaderCtrl::OnChildNotify(amsg, wparam, lparam, presult);
}
